package com.hcy.rabbitruntimeapi.handler;

import com.hcy.rabbitruntimeapi.model.dto.WebSocketKey;
import com.hcy.rabbitruntimeapi.utils.CheckTokenAccess;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @Author huchenying
 * @Description
 * @Date 2021/12/15 18:08
 */
@Component
@ChannelHandler.Sharable
public class MyAccessHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(MyAccessHandler.class);

    @Autowired
    CheckTokenAccess checkTokenAccess;

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        try {
            logger.info("用户下线。。");
//            MyWebSocketFrameHandler.channels.remove(MyWebSocketFrameHandler.webSocketKeys.get(ctx.channel()));
//            MyWebSocketFrameHandler.webSocketKeys.remove(ctx.channel());
            super.channelUnregistered(ctx);
        } catch (Exception e) {
            logger.error("channel清除异常 e -> {}", org.apache.commons.lang.builder.ToStringBuilder.reflectionToString(e));
        }
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg){
        if(msg instanceof HttpRequest){
            logger.debug("websocket token认证");
            try {
                HttpRequest request = (HttpRequest)msg;
                String uri = request.uri();

//                logger.info("uri -> [{}]",uri);
                StringBuilder sb = new StringBuilder(uri);
                String substring = sb.substring(sb.indexOf("=") + 1, sb.length());
                Map<String,String> res = checkTokenAccess.checkToken(substring);
                if(res == null){
                    throw new RuntimeException("token验证失败！");
                }
                //从token中拿出司机的唯一标识信息 和对应的channel绑定到一起。
                WebSocketKey webSocketKey = new WebSocketKey(res.get("user_name"), res.get("client_id"));
                logger.info("放入map webSocketKey = {}", ToStringBuilder.reflectionToString(webSocketKey));
                MyWebSocketFrameHandler.channels.put(webSocketKey,ctx.channel());
                MyWebSocketFrameHandler.webSocketKeys.put(ctx.channel(),webSocketKey);
            } catch (Exception e) {
                logger.error("token验证错误！reason -> {}",e.getMessage());
                ctx.close();
            }
        }
        try {
            super.channelRead(ctx,msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
